Working With Transfer Modes
This section describes some of the ways to use transfer modes for drawing. Note that there are many ways to use transfer modes in drawing; this section mentions only a few of the more common possibilities.See "About Transfer Modes" beginning on page 5-11 for a discussion of the complex process by which QuickDraw GX performs transfer mode calculations.
Simple Source-to-Destination Transfers
To simply draw a color, shape, pattern, or bitmap to the destination, regardless of what the destination currently contains, usegxCopyMode
for all color components. Use identity matrices and make sure all your source colors are within any color limits you are using. Clear all flags (except gxSingleComponentTransfer, if you are using it to make sure all your components usegxCopyMode
with the same color limits and component flags). If your application is drawing or painting with a single color,gxCopyMode
means that the color is applied without modification to all parts of the destination you are drawing to.Copy mode is especially fast and efficient for drawing because the characteristics of the destination are not taken into account.
You can also use
gxAddMode
,gxBlendMode
, orgxMigrateMode
to draw the entire source, but in ways that combine the source and destination. If your application is drawing or painting with a single source color, these modes cause the drawn color or colors to be some combination of the source and the destination. For example, drawing a red apple onto a blue background, usinggxAddMode
in RGB space, results in a magenta apple against a blue background.You can use
gxBlendMode
mode, for example, to lighten or darken all shapes in a picture by some ratio compared to the background (destination). The following code fragment sets the transfer mode of a shape (theShape
) so that the shape's color is blended in a given percentage (thePercentage, normalized togxColorValue1
) with the destination color.
gxTransferMode shapeTransfer; GXGetShapeTransfer(theShape, &shapeTransfer); /* use single-component transfer, blend mode */ shapeTransfer.flags = gxSingleComponentTransfer; shapeTransfer.component[0].mode = gxBlendMode; shapeTransfer.component[0].flags = 0; shapeTransfer.component[0].sourceMinimum = 0; shapeTransfer.component[0].sourceMaximum = gxColorValue1; shapeTransfer.component[0].deviceMinimum = 0; shapeTransfer.component[0].deviceMaximum = gxColorValue1; shapeTransfer.component[0].clampMinimum = 0; shapeTransfer.component[0].clampMaximum = gxColorValue1; shapeTransfer.component[0].operand = ((unsigned long)gxColorValue1) * thePercentage)/100; GXSetShapeTransfer(theShape, &shapeTransfer);Drawing Selected Parts of the Source
There are many ways to transfer only parts of the source image to the destination.You can use
gxMinimumMode
to transfer only those parts of the source that are darker than the destination; if your application is drawing or painting with a single source color,gxMinimumMode
has the effect of darkening and coloring the lighter parts of the destination.You can use
gxMaximumMode
to transfer only those parts of the source that are lighter than the destination; if your application is drawing or painting with a single source color,gxMaximumMode
has the effect of lightening and coloring the darker parts of the destination.You can use
gxCopyMode
but set source color limits so that only colors within certain ranges are transferred. If, for example, part of your source image is bright red, you can set a maximum limit on red intensity in the source; drawing will not occur where that bright red exists, and your destination image will "show through" in those places. You can work in HSV space and set limits on source luminance, so that, for example, your destination image will "show through" the highlights or the shadows of your source image after drawing.If you are drawing in black and white, you can use
gxAndMode
orgxRampAndMode
to transfer only those white parts of the source that are identical to the destination. Alternatively, you can usegxXorMode
orgxRampXorMode
to transfer only those white parts of the source that are different from the destination. The modesgxOrMode
andgxRampOrMode
transfer all of the white parts of the source to the destination. (For
colors other than black and white, Boolean modes give unpredictable results, and pseudo-Boolean modes give results that look like blended versions of black-and-white Boolean.)If you want to mask off parts of the source image that cannot be defined simply, in terms of color or intensity, you can use alpha-channel modes. See the section "Masking" on page 5-48.
Preserving Selected Parts of the Destination
Preserving parts of the destination image is equivalent to drawing only parts of the source, except that it is the characteristics of the destination, not the source, that determine where drawing does and does not occur.The modes
gxMinimumMode
andgxMaximumMode
base drawing on destination characteristics as well as on source characteristics, so you can pick mode and source colors to make sure that desired parts of the destination remain unchanged after drawing. For example, if your destination has bright blue letters on a black background, you can replace that background by drawing withgxMaximumMode
and using any color or image darker than the letters. If you are working in HSV space, you could, for example, turn the background to a different color (of any intensity) by drawing withgxMaximumMode
, and using a color (such as yellow) whose hue value is less than that of the blue letters. You could even leave the background black and change the color of the letters by specifyinggxMinimumMode
for the saturation component and using any source color less saturated than the blue of the letters.You can use
gxCopyMode
but set destination color limits so that drawing occurs only where the destination colors are within certain ranges. If, for example, the black parts of your destination image must be preserved, you can set a minimum limit on the luminance of the destination; drawing will not occur where that black exists, letting the black parts of the destination "show through" the source image after drawing. If you want to preserve only the summer sky in a destination image, set the destination color limits to block drawing in the blue range.If you are drawing in black and white, you can use
gxAndMode
orgxRampAndMode
to preserve only those white parts of the destination that are identical to the source. Alternatively, you can usegxXorMode
orgxRampXorMode
to preserve only those white parts of the destination that are different from the source (and to turn black any white parts of the destination that are also white in the source). The modesgxOrMode
andgxRampOrMode
preserve all of the white parts of the destination, adding to them all of the white parts of the source. (For colors other than black and white, Boolean modes give unpredictable results, and pseudo-Boolean modes give results that look like blended versions of black-and-white Boolean.)Copying or Preserving Luminance
In some cases you may want to alter the colors but not the lightness of an image, or you may want to apply a color, pattern, or texture to an object in a grayscale image. What you are doing is preserving the luminance in either the source or destination, while letting other color components vary when you draw.If, for example, your source image is a picture of a teapot, and your destination image is a color or pattern, you can color the teapot by drawing (in HSV space) with
gxNoMode
in the hue and saturation components, andgxCopyMode
in the value (intensity) component.Alternatively, if the color to apply is in the source image and the teapot is in the destination image, you could use
gxCopyMode
in the hue and saturation components, andgxNoMode
in the value component. (Or you could draw as described in the previous paragraph, but set the gxReverseComponent flag in each component before drawing, although that is a less efficient way to draw.) Figure 5-19 shows an example of drawing by preserving destination luminance in that way. Color Plate 3 at the front of this book shows the same drawing sequence in color.Figure 5-19 Applying color by preserving luminance in the destination
If your application is drawing or painting with a single source color, you can apply that color to the destination image--making it a single hue, but not otherwise changing the destination--by applying
gxCopyMode
to the hue component, andgxNoMode
to the other components, including luminance.Modifying Luminance
Modifying luminance can be used to make a dark image lighter or to make a light image darker, to increase its brightness range (contrast), or to create an overlay or blend of one image onto another, without affecting the hue or saturation of the destination. You can change the luminance of a destination image in several ways, most easily from within HSV or HLS color space.You can draw to the destination using a source image that has any hue or saturation but the desired luminance, using
gxCopyMode
for luminance andgxNoMode
for the other components. (That's the same as preserving the luminance of the source, as described in the previous section.)You can draw to the destination with a source image whose luminance is equal to (or some multiple of, or some absolute amount above or below) the destination image, and use
gxAddMode
orgxCopyMode
. The effect is to uniformly increase or decrease the luminance of the destination image. (Negative luminances are not permissible inputs to transfer mode calculations, although you can achieve the same effect by multiplying luminance by -1 in the transfer mode matrices.) The same effect can be achieved, however, by drawing withgxNoMode
for all components and then applying the result matrix to add to the luminance or multiply it by some factor.Isolating and Modifying Color Ranges
You can restrict drawing to individual colors or ranges of colors in a number of ways. For example, in RGB space you can draw mostly the reds by specifying very restrictive low source color limits for the other components, although this method wouldn't prevent dark non-red colors from being drawn. To draw mostly yellows, you could convert to CMYK space and do the same.In HSV space, you can set the source (or destination) color limits on the hue component, in order to draw (or preserve from drawing) an exact range of hues, independent of their brightness or saturation. You could, for instance, isolate greens in a source landscape image in order to draw fields and trees but not sky; or you could isolate flesh tones in a destination portrait image in order to change hair and clothing colors but not skin color.
You can change the colors in the range you have isolated by using the source, device, or result matrices to shift the hue component. Thus you could change green fields to shades of tan and brown, or even change tan and brown skin to shades of green.
Masking
You can draw an irregular portion of a source image over a destination image, letting the destination show around the edges of the source portion and through holes in it, in several ways. In simple situations, selecting the right transfer mode can accomplish what you need, as discussed under "Drawing Selected Parts of the Source" on page 5-45 and "Preserving Selected Parts of the Destination" on page 5-45.Drawing parts of a complex image on a complex background usually requires the use of a mask image that controls what parts of the source get drawn and what parts do not. QuickDraw GX allows you to integrate a mask with any source or destination image by storing transparency information in the alpha channel of each pixel's color.
You can make parts of your source image transparent and other parts opaque by placing either 0 or
gxColorValue1
, respectively, in the alpha-channel component of each pixel's color. Then, when you draw your source image to the destination, use one of
the alpha-channel transfer modes to get the masking effect you want. The modegxOverMode
is probably the most common transfer mode you'll use; it's likegxCopyMode
with transparency added.The destination image may have transparency also, and if you want to use the result image as a source image for subsequent drawing, you need to calculate the result alpha-channel values as well. With
gxOverMode
for the color components, the most likely mode to use on the alpha channel itself isgxRampOrMode
.Partial Transparency
Besides masking, you can use alpha-channel values to draw images transparently over other images, to give a translucent "stained-glass" or ghostly effect, or to draw a pattern or texture as a transparent surface effect or shadow on an image.In simple situations, just using
gxBlendMode
orgxMigrateMode
might give the translucent effect you need; the intersection of a white rectangle and a black rectangle
is gray, which might be enough. For more sophisticated effects, you can define alpha-channel values in your source image that let the destination image show through partially or completely, and then pick an alpha-channel transfer mode that is appropriate, given the transparency of both source and destination and the transparency you want the result to retain.Anti-Aliasing
Alpha-channel values and alpha-channel modes are also used for anti-aliasing, a drawing technique that minimizes jagged edges around objects drawn on the screen. Type at large sizes is typically drawn with anti-aliasing to smooth its appearance.For anti-aliasing, you first set alpha-channel values to create a mask that defines the opaque parts of your image. Then, at the edges of the opaque portions, you define a zone of partial transparency, one or more pixels wide, that creates a transition from opacity within to transparency without. The color and transparency of each pixel are commonly computed based on the portion of the pixel that the opaque object is calculated to cover. Figure 5-9 on page 5-25 shows an example of this effect.
When you then draw the object with an alpha-channel transfer mode, its edges are feathered, with colors transitional between the source and destination colors. Diagonal lines and curves thus appear smoother and less jagged.
Making Color Separations
Creating color separations from images is fundamentally straightforward with QuickDraw GX. For CMYK color separations, you can use a transfer mode structure that works with CMYK color space and draw your image four times, each time usinggxCopyMode
for all components but modifying the source matrix each time to pass through only the component that you want.You can also create halftones for each separation. See the chapter "View-Related Devices" in this book for a discussion of halftones in QuickDraw GX.
Transfer Modes and Printing
Printers are imaging devices, and the printing components of QuickDraw GX support all transfer modes. When an image is printed, the original state of the destination (paper) is treated as if it were a white image--equivalent to 0xFFFF orgxColorValue1
in all components of RGB space, for example. QuickDraw GX then accumulates all drawing commands before actually printing the page. As it draws each shape on the page, QuickDraw GX combines the source image with the destination, which may be white or may reflect the results of previous drawing, according to the transfer mode selected. After the last shape is drawn, QuickDraw GX prints the result. Thus all transfer modes, and even alpha-channel values, can be accounted for in printing.Even vector devices such as plotters can support transfer modes. The color of each shape the plotter is to draw is combined with the destination according to whatever transfer mode is selected, and at the end the resulting color is printed using one of the available pen colors and patterns.
Printing in QuickDraw GX is optimized for certain transfer mode configurations. In general, printing is fastest using the default ink object's transfer mode (
gxCopyMode
for all components, identity matrices, wide-open color limits). In addition, for fastest printing of 1-bit-per-pixel bitmaps, QuickDraw GX recognizes a special configuration that replicates the QuickDraw srcOr transfer mode on the Macintosh:gxCopyMode
in all components and source color limits set so that only the "on" or "foreground" bits of the image are printed.For more information on printing for applications, see Inside Macintosh: QuickDraw GX Printing. For more information on printing for printer drivers and extensions, see Inside Macintosh: QuickDraw GX Printing Extensions and Drivers.